import vtkArrowSource from "@kitware/vtk.js/Filters/Sources/ArrowSource";
import vtkGlyph3DMapper from "@kitware/vtk.js/Rendering/Core/Glyph3DMapper";
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
import vtkPoints from "@kitware/vtk.js/Common/Core/Points";
import vtkDataArray from "@kitware/vtk.js/Common/Core/DataArray";
import type { Vector3 } from "@kitware/vtk.js/types";
import { BActor } from "../Core/BActor";
import { ACTOR_TYPE } from "../";
import vtkColorTransferFunction from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction";
import {
  ColorMode,
  ScalarMode,
} from "@kitware/vtk.js/Rendering/Core/Mapper/Constants";
// base (number, 閿熸枻鎷烽€�): 閿熸枻鎷峰ご閿熸枻鎷烽敓鏂ゆ嫹閿熶茎绛规嫹閿熼ズ鈽呮嫹
// height (number, 閿熸枻鎷烽€�): 閿熸枻鎷峰ご閿熶茎楂樺害鈽呮嫹
// width (number, 閿熸枻鎷烽€�): 閿熸枻鎷峰ご澶撮敓鏂ゆ嫹閿熶茎鍖℃嫹閿熼ズ鈽呮嫹
// thickness (number, 閿熸枻鎷烽€�): 閿熸枻鎷峰ご閿熶茎鐚存嫹鍙栭敓锟�
// center (Vector3, 閿熸枻鎷烽€�): 閿熸枻鎷峰ご閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷蜂綅閿熺煫锝忔嫹閫氶敓鏂ゆ嫹閿熸枻鎷风ず涓轰竴閿熸枻鎷烽敓鏂ゆ嫹缁撮敓鏂ゆ嫹閿熸枻鎷� [x, y, z]閿熸枻鎷�
// pointType (string, 閿熸枻鎷烽€�): 閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷峰ご閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷烽敓閰电鎷烽敓琛楀嚖鎷烽敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷锋寚閿熸枻鎷烽敓鏂ゆ嫹澶撮敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹閿熺粸鏂ゆ嫹閿熸枻鎷烽敓闃惰揪鎷烽敓锟�
// origin (Vector3, 閿熸枻鎷烽€�): 閿熸枻鎷峰ご閿熸枻鎷烽敓鏂ゆ嫹閿熻娇浼欐嫹鑼敓閰殿煉鎷烽敓鏂ゆ嫹閿熺粸鐤氼€变紮鎷烽敓鏂ゆ嫹閿熻娇顒婃嫹閿熸枻鎷烽敓锟� [x, y, z]閿熸枻鎷�
// direction (Vector3, 閿熸枻鎷烽€�): 閿熸枻鎷峰ご閿熶茎鍑ゆ嫹閿熸枻鎷烽€氶敓鏂ゆ嫹閿熸枻鎷风ず涓轰竴閿熸枻鎷烽敓鏂ゆ嫹缁撮敓鏂ゆ嫹閿熸枻鎷� [x, y, z]閿熸枻鎷锋寚閿熸枻鎷烽敓閰靛嚖鎷烽敓琛楅潻鎷烽敓鏂ゆ嫹閿燂拷
export interface TArrowOptions {
  base?: number;
  height?: number;
  width?: number;
  thickness?: number;
  center?: Vector3;
  pointType?: string;
  origin?: Vector3;
  direction?: Vector3;
}
export interface IArrowSourceInitialValues {
  tipResolution?: number;
  tipRadius?: number;
  tipLength?: number;
  shaftResolution?: number;
  shaftRadius?: number;
  invert?: boolean;
  direction?: Vector3;
  pointType?: string;
}
export class TArrow extends BActor {
  readonly type = ACTOR_TYPE.GRAPHIC_ACTOR;
  factorSize = 5;
  createdBy = "default";
  arrowSource: vtkArrowSource;
  instance: vtkActor = vtkActor.newInstance();
  points: vtkPoints = vtkPoints.newInstance();
  normalsArray: vtkDataArray;
  polyData: vtkPolyData = vtkPolyData.newInstance();
  glyphMapper: vtkGlyph3DMapper = vtkGlyph3DMapper.newInstance({
    interpolateScalarsBeforeMapping: false,
    useLookupTableScalarRange: false,
    scalarVisibility: true,
  });
  normalData: Array<number>;
  pointsData: Array<number>;
  private _options: IArrowSourceInitialValues;
  constructor(
    normalData: number[],
    pointsData: number[],
    options?: IArrowSourceInitialValues
  ) {
    super();
    if (options) {
      options.tipResolution = options.tipResolution ?? 4;
      options.tipRadius = options.tipRadius ?? 0.1;
      options.tipLength = options.tipLength ?? 0.35;
      options.shaftResolution = options.shaftResolution ?? 6;
      options.shaftRadius = options.shaftRadius ?? 0.03;
      options.invert = options.invert ?? false;
      options.pointType = options.pointType ?? "sharp";
      this._options = options;
    } else {
      this._options = {
        tipResolution: 4,
        tipRadius: 0.1,
        tipLength: 0.35,
        shaftResolution: 6,
        shaftRadius: 0.03,
        invert: false,
        pointType: "sharp",
      };
    }
    this.normalData = normalData;
    if (pointsData.length !== 0) {
      pointsData = pointsData.map((v: number, index: number) => {
        let tempX = normalData[index];
        if (tempX) {
          tempX = tempX / Math.abs(tempX);
        }
        return v + (tempX * this.factorSize * -1) / 1.5;
      });
    }
    this.pointsData = pointsData;
    this.arrowSource = vtkArrowSource.newInstance(this._options);

    const points = vtkPoints.newInstance();
    this.normalsArray = vtkDataArray.newInstance({
      numberOfComponents: 3,
      values: normalData,
      name: "Normals",
    });
    this.createPoints();
    this.initPolyData();
    this.initGlyphMapper();
    this.setColor([[0.0, 1.0, 0.0, 0.0]]);
  }
  createPoints() {
    this.points.setData(this.pointsData, 3);
  }
  initPolyData() {
    this.polyData.setPoints(this.points);
    this.polyData.getPointData().setNormals(this.normalsArray);
  }
  setColor(color: [number, number, number, number][]) {
    const colorTransferFunction = vtkColorTransferFunction.newInstance();
    color.forEach((point) => colorTransferFunction.addRGBPoint(...point));
    // 鐠佸墽鐤嗘０婊嗗娴肩娀鈧帒鍤遍弫鎵畱閼煎啫娲�
    colorTransferFunction.setRange(0.0, 1.0); // 鐠佸墽鐤嗛懠鍐ㄦ纯娑擄拷 [0.0, 1.0]
    this.glyphMapper.setColorByArrayName("Normals");
    // this.glyphMapper.setColorMode(ColorMode.MAP_SCALARS);
    this.glyphMapper.setScalarMode(ScalarMode.USE_POINT_FIELD_DATA);
    this.glyphMapper.setLookupTable(colorTransferFunction);
    this.instance.setMapper(this.glyphMapper);
  }
  initGlyphMapper() {
    this.glyphMapper.setInputData(this.polyData, 0);
    this.glyphMapper.setInputConnection(this.arrowSource.getOutputPort(), 1);
    this.glyphMapper.setOrientationModeToDirection();
    this.glyphMapper.setScaleModeToScaleByMagnitude();
    this.glyphMapper.setOrientationArray("Normals");
    this.glyphMapper.setScaleFactor(this.factorSize);
    this.instance.setMapper(this.glyphMapper);
  }
}
